package com.huangsm.book.designmodel;

import java.util.HashMap;
import java.util.Map;

/**
 * 享元工程实现类
 * 享元模式和对象池的最大不同在于:享元对象是不可替代的，它们各自都有各自的含义和用途；而对象池中的对象都是等价的，如数据库连接池中的
 * 数据库连接。
 * @author huang
 * @PACKAGE_NAME com.huangsm.book.designmodel
 * @PROJECT_NAME concurrence
 * @date 2019/2/15
 */
public class ReportMangerFactory {
    Map<String, IReportManager> financialReportManager = new HashMap<>();
    Map<String, IReportManager> empolyeeReportManager = new HashMap<>();

    IReportManager getFinancialReportManager(String tenantId) {
        IReportManager r = financialReportManager.get(tenantId);
        if (r == null) {
            r = new FinancialReportManager(tenantId);
            financialReportManager.put(tenantId, r);
        }
        return r;
    }
    IReportManager getEmpolyeeReportManager(String tenantId){
        IReportManager e = empolyeeReportManager.get(tenantId);
        if (e==null){
            e=new EmployeeReportManager(tenantId);
            empolyeeReportManager.put(tenantId,e);
        }
        return e;
    }

    /**
     * 也无需求，确保同一个公司(租户)使用相同的对象产生报表。这是相当有意义的，
     * 否则系统可能会为每个员工生成各自的报表对象，导致系统开销激增。
     * 测试享元模式,
     * @param args
     */
    public static void main(String[] args) {
        /**
         * ReportManagerFactory作为享元工厂，以租客的ID为索引，维护了一个享元对象的集合，
         * 它确保相同租客的请求都返回同一个享元实例，确保享元对象的有效复用。
         */
    ReportMangerFactory rmf=new ReportMangerFactory();
        IReportManager a = rmf.getEmpolyeeReportManager("A");
        IReportManager c = rmf.getEmpolyeeReportManager("C");
        IReportManager b = rmf.getFinancialReportManager("B");
        System.out.println(a.equals(c));
        System.out.println(b.createReport());
        System.out.println(a.createReport());
    }
}
